using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FlatRedBall;
using FlatRedBall.Input;
using FlatRedBall.Graphics;

using Xzipit.GameObjects;
using Xzipit.MenuObjects;
using Xzipit.Utilities;

using Microsoft.Devices;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using FlatRedBall.Math.Geometry;
using Xzipit.Utilities.Gestures;

namespace Xzipit.Screens
{
    public class LevelSelectScreen : Screen
    {
        private List<LevelButton> _buttons;
        private List<int> _numPins;
        private Sprite _logo;
        private Sprite _bg;
        private LevelBox _info;
        private bool _selectedLevel;
        private bool _movingToLevel;

        private List<int> _bestTimes;

        #region Methods

        #region Constructor and Initialize

        public LevelSelectScreen()
            : base("LevelSelectScreen")
        {
            // Don't put initialization code here, do it in
            // the Initialize method below
            //   |   |   |   |   |   |   |   |   |   |   |
            //   |   |   |   |   |   |   |   |   |   |   |
            //   V   V   V   V   V   V   V   V   V   V   V

        }

        public override void Initialize(bool addToManagers)
        {
            _buttons = new List<LevelButton>();
            _bestTimes = new List<int>();
            _numPins = new List<int>();
            _info = new LevelBox("Global");
            _selectedLevel = false;
            _movingToLevel = false;

            // AddToManagers should be called LAST in this method:
            if (addToManagers)
            {
                AddToManagers();
            }
        }

        public override void AddToManagers()
        {
            string contentManagerName = "Global";
            _logo = SpriteManager.AddSprite(@"Content\MenuObjects\levelSelect", contentManagerName);
            _logo.X = 0.0f;
            _logo.Y = 14.0f;
            float pixelsPerUnit = SpriteManager.Camera.PixelsPerUnitAt(_logo.Z);
            _logo.ScaleX = .6f * _logo.Texture.Width / pixelsPerUnit;
            _logo.ScaleY = .6f * _logo.Texture.Height / pixelsPerUnit;

            _bg = SpriteManager.AddSprite(@"Content\Backgrounds\bg" + GameProperties.SelectedWorld,
                                           "Global");
            _bg.Z = -0.1f;
            _bg.PixelScale();

            _info.Y = 7.0f;
            _info.Z = 0.5f;
            //_info.Visible = false;

            InitializeButtons();
            LoadAllLevelRecords();
        }

        #endregion

        #region Public Methods

        public override void Activity(bool firstTimeCalled)
        {
            if (!firstTimeCalled)
            {
                GameGestureManager.Update();

                // get rid of popup or move back to World Select
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                {
                    if (_info.Alpha == 1.0f)
                    {
                        _info.FadeOut();
                        FadeInButtons();
                    }
                    else
                    {
                        this.Move(typeof(Screens.WorldSelectScreen).FullName);
                    }
                }

                
                HandleGestures();
            }
            
        }

        public override void Destroy()
        {
            base.Destroy();
            SpriteManager.RemoveSprite(_logo);
            SpriteManager.RemoveSprite(_bg);
            _info.Destroy();

            foreach (LevelButton b in _buttons)
            {
                b.Destroy();
            }
        }

        private void HandleGestures()
        {
            if (!_movingToLevel)
            {
                if (!_info.Fading)
                {
                    foreach (GameGesture g in GameGestureManager.Gestures)
                    {
                        Vector3 gestureEnd = g.End;
                        // handle play button collision
                        if (g.GameGestureType == GameGestureType.Tap
                            && _info.Collision.IsPointInside(ref gestureEnd)
                            && _info.Alpha == 1.0f
                            && _selectedLevel)
                        {
                            GameProperties.Vibrate(.05);
                            _info.PlaySound();
                            _info.FadeOut();
                            foreach (LevelButton b in _buttons)
                            {
                                b.FadeOut();
                            }
                            _movingToLevel = true;
                        }

                        if (_info.Alpha == 0.0f)
                        {
                            foreach (LevelButton b in _buttons)
                            {
                                if (b.Enabled
                                && g.GameGestureType == GameGestureType.Tap
                                && b.Collision.IsPointInside(ref gestureEnd))
                                {
                                    GameProperties.Vibrate(.05);
                                    GameProperties.SelectedLevel = b.Level;
                                    GameProperties.LevelPin = _bestTimes[b.Level - 1];
                                    string levelBoxInfo =
                                        Level.GetLevelBoxInfo(GameProperties.SelectedWorld,
                                        GameProperties.SelectedLevel);
                                    //LevelManager.LoadInfo();
                                    b.PlaySound();

                                    // start the fading
                                    _info.FadeIn(levelBoxInfo);
                                    PartialFadeOutButtons();

                                    _selectedLevel = true;
                                    break;
                                }
                            }
                        }
                    }
                }
                else
                {
                    _info.CheckFadingStatus();
                    foreach (LevelButton b in _buttons)
                    {
                        b.DoneFading();
                    }
                }
            }
            else
            {
                if (_info.CheckFadingStatus())
                {
                    this.Move(typeof(Screens.GameScreen).FullName);                    
                }
            }
        }

        #endregion

        #region Private Initialization Methods
        private void InitializeButtons()
        {
            float startingY = 8.0f;
            float dy = 6.0f;
            float startingX = -6.0f;
            float dx = 6.0f;
            int levelsPerRow = 3;

            for (int i = 0; i < GameProperties.LEVELS_PER_WORLD; i++)
            {
                _buttons.Add(new LevelButton("Global", i + 1));
                _buttons[i].X = startingX + ((i % levelsPerRow) * dx);
                _buttons[i].Y = startingY - ((i / levelsPerRow) * dy);
                _buttons[i].Alpha = 0.0f;
            }

            foreach (LevelButton b in _buttons)
            {
                b.FadeIn();
            }
        }

        private void LoadAllLevelRecords()
        {
            _bestTimes = GameProperties.Save.GetLevelPinColors(GameProperties.SelectedWorld);
            _numPins = GameProperties.Save.GetNumberOfPinsToUnlock(GameProperties.SelectedWorld);
            int i = 0;

            foreach (LevelButton lb in _buttons)
            {
                lb.SetColor(_bestTimes[i]);
                lb.SetLocked(_numPins[i]);

                i++;
            }
        }

        #endregion

        #region Private Methods

        private void FadeOutButtons()
        {
            foreach (LevelButton b in _buttons)
            {
                b.FadeOut();
            }
        }

        private void PartialFadeOutButtons()
        {
            foreach (LevelButton b in _buttons)
            {
                b.PartialFadeOut();
            }
        }

        private void FadeInButtons()
        {
            foreach (LevelButton b in _buttons)
            {
                b.FadeIn();
            }
        }

        #endregion

        #endregion
    }
}

